package com.onemile.data;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlSerializer;

import com.onemile.utils.UtiGZip;
import com.onemile.utils.UtiMobileCrypto;

import android.R.integer;
import android.util.Xml;

/**
 * 业务报文解析器
 */
public class EXml_bak
{
   private Head _head;
   private Body _body;
   private Object _tag;

   public EXml_bak()
   {
	  _head = new Head();
	  _body = new Body();
   }

   public EXml_bak(String xml)
   {
	  this();
	  fromXml(xml);
   }

   public boolean isFieldListNode(Node n)
   {
	  int size = n.getChildNodes().getLength();
	  if (size < 1)
	  {
		 return false;
	  }
	  NodeList nList = n.getChildNodes();
	  for (int i = 0; i < size; i++)
	  {
		 if (nList.item(i).getNodeType() == Node.ELEMENT_NODE)
		 {
			return true;
		 }
	  }
	  return false;
   }

   public boolean isEmpty()
   {
	  return getHead().getPageCount() == 0;
   }

   public boolean isEndPage()
   {
	  return getHead().getPageCount() == getHead().getPageCount();
   }

   public boolean hasError()
   {
	  return getHead().hasError();
   }

   public Head getHead()
   {
	  return _head;
   }

   public Body getBody()
   {
	  return _body;
   }

   public Object getTag()
   {
	  return _tag;
   }

   public void setTag(Object tag)
   {
	  _tag = tag;
   }

   public void merge(EXml_bak other)
   {
	  if (other == null || hasError())
	  {
		 return;
	  }

	  // 合并 Head
	  getHead().reset(other.getHead());

	  // 合并 Body 下的 FieldList
	  FieldList f = other.getBody().getFirstFieldList();
	  if (f != null)
	  {
		 FieldList m = getBody().getFirstFieldList();
		 if (m != null)
		 {
			int oldMaxName = 0;
			ArrayList<FieldList> list = m.getFieldLists();
			if (list != null && list.size() > 0)
			{
			   String strName = list.get(list.size() - 1).getName();
			   oldMaxName = Integer.parseInt(strName);
			}
			for (FieldList v : f.getFieldLists())
			{
			   int name = Integer.parseInt(v.getName()) + oldMaxName + 1;
			   v.setName(String.valueOf(name));
			   m.addFieldList(v);
			}
		 }
		 else
		 {
			getBody().addFieldList(f);
		 }
	  }
   }

   public void clear()
   {
	  _head.clear();
	  _body.clear();
   }

   public void fromXml(String xml)
   {
	  if (xml == null || xml.equals(""))
	  {
		 return;
	  }

	  DocumentBuilderFactory factory = null;
	  DocumentBuilder docBuilder = null;
	  Document doc = null;
	  try
	  {
		 InputStream in = new ByteArrayInputStream(xml.getBytes());
		 factory = DocumentBuilderFactory.newInstance();
		 docBuilder = factory.newDocumentBuilder();
		 doc = docBuilder.parse(in);
		 Element root = doc.getDocumentElement();

		 if (root.getTagName().equals("Result"))
		 {
			if (root.getFirstChild() != null)
			{
			   fromRawXml(root.getFirstChild().getNodeValue());
			}
		 }
		 else if (root.getTagName().equals("Error"))
		 {
			getHead().setRespCode(root.getAttribute("ErrId"));
			getHead().setRespMsg(root.getAttribute("ErrMsg"));
		 }
		 else
		 {
			fromRawXml(xml);
		 }
	  }
	  catch (Exception e)
	  {

	  }
	  finally
	  {
		 doc = null;
		 docBuilder = null;
		 factory = null;
	  }
   }

   public void fromRawXml(String xml)
   {
	  if (xml == null || xml.equals(""))
	  {
		 return;
	  }

	  DocumentBuilderFactory factory = null;
	  DocumentBuilder docBuilder = null;
	  Document doc = null;
	  try
	  {
		 InputStream in = new ByteArrayInputStream(xml.getBytes());
		 factory = DocumentBuilderFactory.newInstance();
		 factory.setCoalescing(true);
		 docBuilder = factory.newDocumentBuilder();
		 doc = docBuilder.parse(in);
		 Element root = doc.getDocumentElement();

		 // head
		 NodeList nodeList = root.getElementsByTagName("Head");
		 if (nodeList != null && nodeList.getLength() > 0)
		 {
			getHead().fromHeadXml((Element) nodeList.item(0));
		 }

		 // body
		 nodeList = root.getElementsByTagName("Body");
		 if (nodeList != null && nodeList.getLength() > 0)
		 {
			getBody().fromBodyXml((Element) nodeList.item(0));
		 }
	  }
	  catch (Exception e)
	  {

	  }
	  finally
	  {
		 doc = null;
		 docBuilder = null;
		 factory = null;
	  }
   }

   public String toXml()
   {
	  XmlSerializer serializer = Xml.newSerializer();
	  StringWriter writer = new StringWriter();
	  try
	  {
		 serializer.setOutput(writer);
		 serializer.startDocument("utf-8", true);
		 serializer.startTag("", "Message");
		 getHead().toHeadXml(serializer);
		 getBody().toBodyXml(serializer);
		 serializer.endTag("", "Message");
		 serializer.endDocument();
		 return writer.toString();
	  }
	  catch (Exception e)
	  {

	  }
	  finally
	  {
		 serializer = null;
		 writer = null;
	  }
	  return null;
   }

   public byte[] toBytes() throws UnsupportedEncodingException
   {
	  return (this.toXml().replace("&#64;", "@")).getBytes("utf-8");
   }

   /**
    * 报文的 Head ==============================================================
    */
   public class Head
   {
	  public static final int DEFAULT_PAGE_SIZE = 10;
	  public static final int MAX_RECORD_COUNT = 50;
	  private final String SUCCESS_CODE = "000000000000";
	  private LinkedHashMap<String, String> _dict;

	  public Head()
	  {
		 Date date = new Date(System.currentTimeMillis());
		 String t = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);

		 _dict = new LinkedHashMap<String, String>();
		 _dict.put("Version", "1.0");
		 _dict.put("PostTime", t);
		 _dict.put("APICode", "");
		 _dict.put("RspCode", SUCCESS_CODE);
		 _dict.put("RspMsg", "");
		 _dict.put("UseGZip", "0");
		 _dict.put("PageNo", "1");
		 _dict.put("PageSize", String.valueOf(DEFAULT_PAGE_SIZE));
		 _dict.put("PageCount", "0");
	  }

	  private LinkedHashMap<String, String> getFields()
	  {
		 return _dict;
	  }

	  public String getVersion()
	  {
		 return _dict.get("Version");
	  }

	  public String getPostTime()
	  {
		 return _dict.get("PostTime");
	  }

	  public String getApiCode()
	  {
		 return _dict.get("APICode");
	  }

	  public String getRespCode()
	  {
		 return _dict.get("RspCode");
	  }

	  public String getRespMsg()
	  {
		 return _dict.get("RspMsg");
	  }

	  public boolean getIsGZip()
	  {
		 return Integer.parseInt(_dict.get("UseGZip")) == 1;
	  }

	  public int getPageNo()
	  {
		 String page = _dict.get("PageNo");
		 if (page == null || page.equals(""))
		 {
			return 0;
		 }
		 else
		 {
			return Integer.parseInt(page);
		 }
	  }

	  public int getPageSize()
	  {
		 String size = _dict.get("PageSize");
		 if (size == null || size.equals(""))
		 {
			return 0;
		 }
		 else
		 {
			return Integer.parseInt(size);
		 }
	  }

	  public int getPageCount()
	  {
		 String pageCount = _dict.get("PageCount");
		 if (pageCount == null || pageCount.equals(""))
		 {
			return 0;
		 }
		 else
		 {
			return Integer.parseInt(pageCount);
		 }
	  }

	  public void setApiCode(String code)
	  {
		 _dict.put("APICode", code);
	  }

	  public void setRespCode(String code)
	  {
		 _dict.put("RspCode", code);
	  }

	  public void setRespMsg(String msg)
	  {
		 _dict.put("RspMsg", msg);
	  }

	  public void setIsGZip(boolean isGZip)
	  {
		 _dict.put("UseGZip", isGZip ? "1" : "0");
	  }

	  public void setPageIndex(int pageIndex)
	  {
		 _dict.put("PageNo", String.valueOf(pageIndex));
	  }

	  public void setPageSize(int pageSize)
	  {
		 _dict.put("PageSize", String.valueOf(pageSize));
	  }

	  public void setPageCount(int pageCount)
	  {
		 _dict.put("PageCount", String.valueOf(pageCount));
	  }

	  public boolean hasError()
	  {
		 if (getRespCode() == null)
		 {
			return false;
		 }
		 else
		 {
			return !SUCCESS_CODE.equals(getRespCode());
		 }
	  }

	  public void reset(Head head)
	  {
		 LinkedHashMap<String, String> map = head.getFields();
		 if (map != null && map.size() > 0)
		 {
			clear();
			for (String key : map.keySet())
			{
			   _dict.put(key, map.get(key));
			}
		 }
	  }

	  public void clear()
	  {
		 _dict.clear();
	  }

	  public void fromHeadXml(Element elem)
	  {
		 NodeList nodes = elem.getChildNodes();
		 int size = nodes.getLength();
		 if (size > 0)
		 {
			for (int i = 0; i < size; i++)
			{
			   if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE)
			   {
				  Element e = (Element) nodes.item(i);
				  String name = e.getNodeName();
				  String value = null;
				  if (e.getFirstChild() != null)
				  {
					 value = e.getFirstChild().getNodeValue();
				  }
				  _dict.put(name, value == null ? "" : value);
			   }
			}
		 }
	  }

	  public void toHeadXml(XmlSerializer ser) throws Exception
	  {
		 ser.startTag("", "Head");
		 for (String name : getFields().keySet())
		 {
			// ser.startTag("", "field");
			// ser.attribute("", "name", name.toUpperCase());
			// ser.text(getFields().get(name));
			// ser.endTag("", "field");
			ser.startTag("", name);
			ser.text(getFields().get(name));
			ser.endTag("", name);
		 }
		 ser.endTag("", "Head");
	  }
   }

   /**
    * 报文的 body =============================================================
    */
   public class Body
   {
	  private LinkedHashMap<String, BaseField> _dictBody;

	  public Body()
	  {
		 _dictBody = new LinkedHashMap<String, BaseField>();
	  }

	  /**
	   * 所有的孩子，包括 Field FieldList
	   */
	  private BaseField[] getChilds()
	  {
		 return _dictBody.values().toArray(new BaseField[_dictBody.size()]);
	  }

	  /**
	   * 所有的 Field 值
	   */
	  public ArrayList<Field> getFields()
	  {
		 ArrayList<Field> list = new ArrayList<Field>();
		 for (BaseField f : _dictBody.values())
		 {
			if (f instanceof Field)
			{
			   list.add((Field) f);
			}
		 }
		 return list;
	  }

	  /**
	   * 所有的 FieldList 值
	   */
	  public ArrayList<FieldList> getFieldLists()
	  {
		 ArrayList<FieldList> list = new ArrayList<FieldList>();
		 for (BaseField f : _dictBody.values())
		 {
			if (f instanceof FieldList)
			{
			   list.add((FieldList) f);
			}
		 }
		 return list;
	  }

	  public FieldList getFieldList(int index)
	  {
		 ArrayList<FieldList> list = getFieldLists();
		 if (list != null && index < list.size())
		 {
			return list.get(index);
		 }
		 else
		 {
			return null;
		 }
	  }

	  public FieldList getFirstFieldList()
	  {
		 return getFieldList(0);
	  }

	  public FieldList getDataRow(int index)
	  {
		 FieldList fl = getFirstFieldList();
		 if (fl != null && index < fl.getChildCount())
		 {
			BaseField bf = fl.getChilds().get(index);
			if (bf instanceof FieldList)
			{
			   return (FieldList) bf;
			}
			else
			{
			   return null;
			}
		 }
		 return null;
	  }

	  public void removeDataRow(String name)
	  {
		 FieldList fl = getFirstFieldList();
		 if (fl != null)
		 {
			fl.removeFieldList(name);
		 }
	  }

	  public int getDataRowCount()
	  {
		 FieldList fl = getFirstFieldList();
		 if (fl != null)
		 {
			return fl.getChildCount();
		 }
		 else
		 {
			return 0;
		 }
	  }

	  /**
	   * 根据 Field 名获取其值
	   * 
	   * @param fieldName
	   * @return
	   */
	  public String getFieldValue(String fieldName)
	  {
		 String up = fieldName.toUpperCase();
		 if (_dictBody.containsKey(up))
		 {
			if (_dictBody.get(up) instanceof Field)
			{
			   return _dictBody.get(up).getValue();
			}
		 }
		 return "";
	  }

	  /**
	   * 根据 Field 名获取 Field
	   * 
	   * @param fieldName
	   * @return
	   */
	  public Field getField(String fieldName)
	  {
		 String up = fieldName.toUpperCase();
		 if (_dictBody.containsKey(up))
		 {
			if (_dictBody.get(up) instanceof Field)
			{
			   return (Field) _dictBody.get(up);
			}
		 }
		 return null;
	  }

	  /**
	   * 加入单个字段值
	   */
	  public Field addField(String name, String value)
	  {
		 return addField(new Field(name, value));
	  }

	  /**
	   * 加入单个字段值
	   */
	  public Field addField(String name)
	  {
		 return addField(new Field(name, ""));
	  }

	  /**
	   * 加入 Field
	   */
	  private Field addField(Field field)
	  {
		 if (field != null)
		 {
			_dictBody.put(field.getName(), field);
		 }
		 return field;
	  }

	  /**
	   * 加入 FieldList
	   */
	  public FieldList addFieldList(String name)
	  {
		 return addFieldList(new FieldList(name));
	  }

	  /**
	   * 加入 FieldList
	   */
	  private FieldList addFieldList(FieldList fl)
	  {
		 if (fl != null)
		 {
			if (!_dictBody.containsKey(fl.getName()))
			{
			   _dictBody.put(fl.getName(), fl);
			   return fl;
			}
			else
			{
			   return null;
			}
		 }
		 else
		 {
			return null;
		 }
	  }

	  public void clear()
	  {
		 if (_dictBody != null)
		 {
			for (String key : _dictBody.keySet())
			{
			   BaseField f = _dictBody.get(key);
			   f.clear();
			   f = null;
			}
			_dictBody.clear();
		 }
	  }

	  private Element covertGZipXml(Element elem)
	  {
		 if (elem.getFirstChild() == null)
		 {
			return null;
		 }

		 Element root = null;
		 DocumentBuilderFactory factory = null;
		 DocumentBuilder docBuilder = null;
		 Document doc = null;
		 try
		 {
			// 解压还原
			String text = elem.getFirstChild().getNodeValue();
			byte[] bytes = UtiMobileCrypto.fromHexString(text);
			String xml = new String(UtiGZip.decompress(bytes), "utf-8");
			xml = "<Body>" + xml + "</Body>";

			InputStream in = new ByteArrayInputStream(xml.getBytes());
			factory = DocumentBuilderFactory.newInstance();
			factory.setCoalescing(true);
			docBuilder = factory.newDocumentBuilder();
			doc = docBuilder.parse(in);
			root = doc.getDocumentElement();
		 }
		 catch (Exception e)
		 {
			e.printStackTrace();
		 }
		 finally
		 {
			doc = null;
			docBuilder = null;
			factory = null;
		 }
		 return root;
	  }

	  public void fromBodyXml(Element elem)
	  {
		 Element bodyElem = elem;
		 if (getHead().getIsGZip())
		 {
			bodyElem = covertGZipXml(elem);
		 }

		 // 子元素
		 NodeList nodes = bodyElem.getChildNodes();
		 int lenth = nodes.getLength();
		 for (int i = 0; i < lenth; i++)
		 {
			Node node = nodes.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE)
			{
			   if (node.getChildNodes().getLength() == 0)
			   {
				  addField(new Field((Element) node));
			   }
			   else if (node.getChildNodes().getLength() > 0)
			   {
				  addFieldList(new FieldList((Element) node));
			   }
			}
		 }
	  }

	  public void toBodyXml(XmlSerializer ser) throws Exception
	  {
		 ser.startTag("", "Body");
		 for (BaseField v : getChilds())
		 {
			v.toXml(ser);
		 }
		 ser.endTag("", "Body");
	  }
   }

   /**
    * 报文的 Field ===========================================================
    */
   public class Field extends BaseField
   {
	  // 存放扩展的属性
//	  private LinkedHashMap<String, String> _extensions;
//
//	  public LinkedHashMap<String, String> getExtensions()
//	  {
//		 if (_extensions == null)
//		 {
//			_extensions = new LinkedHashMap<String, String>();
//		 }
//		 return _extensions;
//	  }

//	  public int getExtensionCount()
//	  {
//		 if (_extensions == null)
//		 {
//			return 0;
//		 }
//		 else
//		 {
//			return _extensions.size();
//		 }
//	  }

	  public Field(String name, String value)
	  {
		 _name = name;
		 _value = value;
	  }

	  public Field(Element elem)
	  {
		 fromXml(elem);
	  }

	  @Override
	  public void clear()
	  {

	  }

	  // field
	  @Override
	  public void fromXml(Element elem)
	  {
		 //节点包括其他属性
//		 String name = elem.getNodeName();
//		 String value = elem.getNodeValue();
//		 if (name.equals("name"))
//		 {
//			setName(value);
//
//			// innerText
//			String innerText = "";
//			if (elem.getFirstChild() != null)
//			{
//			   innerText = elem.getFirstChild().getNodeValue();
//			}
//			setValue(innerText == null ? "" : innerText);
//		 }
//		 else
//		 {
//			getExtensions().put(name, value == null ? "" : value);
//		 }
		 String name = elem.getNodeName();
		 String value = elem.getNodeValue();
		 if(name!=null&&!name.equals(""))
		 {
			setName(name);
			String innerText = "";
			if (elem.getFirstChild() != null)
			{
			   innerText = elem.getFirstChild().getNodeValue();
			}
			setValue(innerText == null ? "" : innerText);
		 }

	  }

	  // field
	  @Override
	  public void toXml(XmlSerializer ser) throws Exception
	  {
		 ser.startTag("", getName());
		//节点包括其他属性
//		 if (getExtensionCount() > 0)
//		 {
//			LinkedHashMap<String, String> ext = getExtensions();
//			for (String name : ext.keySet())
//			{
//			   ser.attribute("", name, ext.get(name));
//			}
//		 }
		 ser.text(getValue());
		 ser.endTag("", getName());
	  }
   }

   /**
    * 报文的 Body 下的 FieldList
    * ==============================================================
    */
   public class FieldList extends BaseField
   {
	  private FieldList _owner;
	  private LinkedHashMap<String, BaseField> _dict;
	  private ArrayList<BaseField> _childs;

	  private FieldList()
	  {
		 _dict = new LinkedHashMap<String, BaseField>();
		 _childs = new ArrayList<BaseField>();
	  }

	  public FieldList(String name)
	  {
		 this();
		 setName(name);
	  }

	  public FieldList(Element elem)
	  {
		 this();
		 fromXml(elem);
	  }

	  public FieldList getOwner()
	  {
		 return _owner;
	  }

	  public void setOwner(FieldList owner)
	  {
		 _owner = owner;
	  }

	  /**
	   * 所有的孩子，包括 Field FieldList
	   */
	  public ArrayList<BaseField> getChilds()
	  {
		 return _childs;
	  }

	  /**
	   * 所有的孩子总数
	   */
	  public int getChildCount()
	  {
		 return _childs.size();
	  }

	  /**
	   * 所有的 Field 值
	   */
	  public ArrayList<Field> getFields()
	  {
		 ArrayList<Field> list = new ArrayList<Field>();
		 for (BaseField f : _dict.values())
		 {
			if (f instanceof Field)
			{
			   list.add((Field) f);
			}
		 }
		 return list;
	  }

	  /**
	   * 所有的 FieldList 值
	   */
	  public ArrayList<FieldList> getFieldLists()
	  {
		 ArrayList<FieldList> list = new ArrayList<FieldList>();
		 for (BaseField f : _dict.values())
		 {
			if (f instanceof FieldList)
			{
			   list.add((FieldList) f);
			}
		 }
		 return list;
	  }

	  public FieldList getDataRow(int index)
	  {
		 ArrayList<FieldList> list = getFieldLists();
		 if (index < list.size())
		 {
			return list.get(index);
		 }
		 else
		 {
			return null;
		 }
	  }

	  private void removeFieldList(String name)
	  {
		 FieldList fl = getFieldList(name);
		 if (fl != null)
		 {
			_dict.remove(fl.getName());
			_childs.remove(fl);
		 }
	  }

	  /**
	   * 根据名称获取 FieldList
	   */
	  public FieldList getFieldList(String name)
	  {
		 String up = name.toUpperCase();
		 if (_dict.containsKey(up))
		 {
			if (_dict.get(up) instanceof FieldList)
			{
			   return (FieldList) _dict.get(up);
			}
			else
			{
			   return null;
			}
		 }
		 else
		 {
			return null;
		 }
	  }

	  /**
	   * 根据 Field 名获取其值
	   * 
	   * @param fieldName
	   * @return
	   */
	  public String getFieldValue(String fieldName)
	  {
		 String up = fieldName.toUpperCase();
		 if (_dict.containsKey(up))
		 {
			if (_dict.get(up) instanceof Field)
			{
			   return _dict.get(up).getValue();
			}
		 }
		 return "";
	  }

	  /**
	   * 根据 Field 名获取 Field
	   * 
	   * @param fieldName
	   * @return
	   */
	  public Field getField(String fieldName)
	  {
		 String up = fieldName.toUpperCase();
		 if (_dict.containsKey(up))
		 {
			if (_dict.get(up) instanceof Field)
			{
			   return (Field) _dict.get(up);
			}
		 }
		 return null;
	  }

	  /**
	   * 加入 Field
	   */
	  public Field addField(String name, String value)
	  {
		 return addField(new Field(name, value));
	  }

	  /**
	   * 加入 Field
	   */
	  public Field addField(Field field)
	  {
		 if (field != null)
		 {
			_dict.put(field.getName(), field);
			_childs.add(field);
		 }
		 return field;
	  }

	  /**
	   * 加入 FieldList
	   */
	  public FieldList addFieldList(String name)
	  {
		 return addFieldList(new FieldList(name));
	  }

	  /**
	   * 加入 FieldList
	   */
	  public FieldList addFieldList(FieldList fl)
	  {
		 if (fl != null)
		 {
			fl.setOwner(this);
			if (!_dict.containsKey(fl.getName()))
			{
			   _dict.put(fl.getName(), fl);
			   _childs.add(fl);
			   return fl;
			}
			else
			{
			   return null;
			}
		 }
		 else
		 {
			return null;
		 }
	  }

	  @Override
	  public void clear()
	  {
		 for (BaseField f : getChilds())
		 {
			f.clear();
		 }

		 _childs.clear();
		 _dict.clear();
	  }

	  // fieldlist
	  @Override
	  public void fromXml(Element elem)
	  {
		 setName(elem.getNodeName());

		 if (!isFieldListNode(elem))
		 {
			addField(new Field(elem));
		 }
		 else
		 {
			NodeList nodes = elem.getChildNodes();
			int size = nodes.getLength();
			for (int i = 0; i < size; i++)
			{
			   Node node = nodes.item(i);
			   if (node.getNodeType() == Node.ELEMENT_NODE)
			   {
				  if (!isFieldListNode(node))
				  {
					 addField(new Field((Element) node));
				  }
				  else
				  {
					 addFieldList(new FieldList((Element) node));
				  }
			   }
			}
		 }
		 // 子节点

	  }

	  // fieldlist
	  @Override
	  public void toXml(XmlSerializer ser) throws Exception
	  {
		 // 自身节点开始
		 ser.startTag("", getName());
		 // 子元素
		 for (BaseField item : getChilds())
		 {
			item.toXml(ser);
		 }
		 // 自身节点结束
		 ser.endTag("", getName());
	  }
   }

   /**
    * Field FieldList 基类
    * =============================================================
    */
   public abstract class BaseField
   {
	  protected String _name;
	  protected String _value;
	  protected Object _tag;

	  public String getName()
	  {
		 return _name;
	  }

	  public String getValue()
	  {
		 return _value;
	  }

	  public Object getTag()
	  {
		 return _tag;
	  }

	  public void setName(String name)
	  {
		 _name = name;
	  }

	  public void setValue(String value)
	  {
		 _value = value;
	  }

	  public void setTag(Object tag)
	  {
		 _tag = tag;
	  }

	  public abstract void clear();

	  public abstract void fromXml(Element elem);

	  public abstract void toXml(XmlSerializer ser) throws Exception;
   }
}
